import axios, { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { pick } from 'lodash-es';
type AxiosRequestConfigField = keyof AxiosRequestConfig;

/**
 * 有效的axiosConfig的配置项fields 数组结构支持外部push扩展
 */

const effectiveAxiosConfigFields: AxiosRequestConfigField[] = [
    'url',
    'params',
    'data',
    'headers',
    'method',
    'baseURL',
    'timeout',
    'paramsSerializer',
    'cancelToken',
    'transformRequest',
    'transformResponse',
    'withCredentials',
];

const getAxiosConfig = (opts: AxiosRequestConfig) => {
    return Object.assign(
        {
            baseURL: '',
            timeout: 20000,
            headers: {},
            validateStatus() {
                return true;
            },
            responseType: 'json',
            withCredentials: true,
        },
        opts,
    );
};

export const instance = axios.create(
    getAxiosConfig({
        adapter: async (config: AxiosRequestConfig) => {
            return axios(getAxiosConfig(pick(config, effectiveAxiosConfigFields)));
        },
    }),
);

// 请求拦截器，可以在这里对请求做一些通用处理，比如添加通用请求头等
instance.interceptors.request.use(
    (req: InternalAxiosRequestConfig<unknown>) => {
        return req;
    },
    err => {
        return Promise.resolve(err);
    },
);

// 返回体拦截器，可以在这里对返回体做通用的验证、处理
instance.interceptors.response.use(
    (res: AxiosResponse) => {
        return res;
    },
    error => {
        if (axios.isCancel(error)) {
            console.log('Request canceled', error.message);
        }
        return Promise.reject(error);
    },
);
